App.Note = angular.module('Note', []).
controller('Note.Ctrl', ['MainApp.DataService', 'Note.Factory', '$rootScope', '$scope', 'MainApp.ConfigService', function (Data, Note, $rootScope, $scope, Config) {
	$scope.$on('Note.create', function (event, note) {
		Note.create(Note.fromObject(note), Data.User.actualUser).then(
			function (note) {
				Data.User.actualUser.addNote(note);
				Data.Note.actualNote = Note.fromObject(Config.Note.emptyNote);
				$rootScope.$broadcast('App.refreshState');
			},
			function (error) {
				$rootScope.$broadcast('Error.catch', error);
			}
		);
	});
	$scope.$on('Note.save', function (event, note) {
		var actual = Data.Note.actualNote;
		actual.setTitle(note.title);
		actual.setIntro(note.intro);
		actual.setContent(note.content);
		actual.save().then(
			function () {
				$rootScope.$broadcast('App.refreshState');
			},
			function (error) {
				$rootScope.$broadcast('Error.catch', error);
			}
		);
	});
	$scope.$on('Note.delete', function (event, note) {
		var actual = Data.Note.actualNote,
			actualId = actual.getId();
		actual.remove().then(
			function () {
				Data.User.actualUser.getNotes().removeNote(actualId);
				Data.Note.actualNote = Note.fromObject(Config.Note.emptyNote);
				$rootScope.$broadcast('App.refreshState');
			},
			function (error) {
				$rootScope.$broadcast('Error.catch', error);
			}
		);
	});
}]).
service('Note.ConfigService', ['MainApp.ConfigService', function (Config) {
	this.templateDir = Config.Template.templateDir+'Note/';
	this.modes = {
		edit: 'edit',
		create: 'create',
		none: 'none'
	}
}]).
factory('Note.Factory', ['Api.Service', 'Error.Service', '$q', 'MainApp.ConfigService', 'Tools.Service', 'MainApp.DataService', function (Api, Error, $q, Config, Tools, Data) {
	function Note () {
		var that = this,
			id,
			title,
			intro,
			content;
		function setId (nID) {
			id = nID;
		}
		function getId () {
			return id;
		}
		function setTitle (nTitle) {
			title = nTitle;
		}
		function getTitle () {
			return title;
		}
		function setIntro (nIntro) {
			intro = nIntro;
		}
		function getIntro () {
			return intro;
		}
		function setContent (nContent) {
			content = nContent;
		}
		function getContent () {
			return content;
		}
		function toObject () {
			return {
				id: id,
				title: title,
				intro: intro,
				content: content
			}
		}
		function save () {
			var updatenote = Api.UpdateNote.fromObject({
					user: Data.User.actualUser.getLogin(),
					pass: Data.User.actualUser.getPassword(),
					nid: id,
					topic: title,
					summary: intro,
					text: content,
					keys: Data.User.actualUser.getLogin()
				}),
				d = $q.defer();
			Api.getData(updatenote, function (response) {
				if(response) {
					if(response.rez == Config.Api.validResponseValue) {
						d.resolve();
					} else {
						d.reject(new Error.ApiError());
					}
				} else {
					d.reject(new Error.BaseError());
				}
			});
			return d.promise;
		}
		function remove () {
			var delnote = Api.DelNote.fromObject({
					user: Data.User.actualUser.getLogin(),
					pass: Data.User.actualUser.getPassword(),
					id: id
				}),
				d = $q.defer();
			Api.getData(delnote, function (response) {
				if(response) {
					if(response.rez == Config.Api.validResponseValue) {
						d.resolve();
					} else {
						d.reject(new Error.ApiError());
					}
				} else {
					d.reject(new Error.BaseError());
				}
			});
			return d.promise;
		}
		(function construct () {
			that.setId = setId;
			that.getId = getId;
			that.setTitle = setTitle;
			that.getTitle = getTitle;
			that.setIntro = setIntro;
			that.getIntro = getIntro;
			that.setContent = setContent;
			that.getContent = getContent;
			that.toObject = toObject;
			that.save = save;
			that.remove = remove;
		})();
	}
	Note.getUserNotes = function (user) {
		var notes = new Api.GetNotes.fromObject({
				user: user.getLogin(),
				pass: user.getPassword()
			}),
			d = $q.defer(),
			group,
			NotesGroup = Tools.inject('NotesGroup.Factory');
		Api.getData(notes, function (response) {
			if(!response) {
				d.reject(new Error.BaseError());
			} else {
				if(response.rez == Config.Api.validResponseValue) {
					d.resolve(NotesGroup.getByIds(response.notes));
				} else {
					d.reject(new Error.ApiError());
				}
			}
		});
		return d.promise;
	}
	Note.getById = function (id) {
		var getnote = new Api.GetNote.fromObject({
				id: id,
				user: Data.User.actualUser
			}),
			d = $q.defer();
		Api.getData(getnote, function (response) {
			if(!response) {
				d.reject(new Error.BaseError());
			} else {
				if(response.rez == Config.Api.validResponseValue) {
					d.resolve(Note.fromObject({
						id: id,
						title: response.topic,
						intro: response.summary,
						content: response.text || ''
					}));
				} else {
					d.reject(new Error.ApiError());
				}
			}
		});
		return d.promise;
	}
	Note.fromObject = function (obj) {
		var note = new Note();
		note.setId(obj.id);
		note.setTitle(obj.title);
		note.setIntro(obj.intro);
		note.setContent(obj.content);
		return note;
	}
	Note.create = function (note, user) {
		var newnote = Api.NewNote.fromObject({
				user: user.getLogin(),
				pass: user.getPassword(),
				topic: note.getTitle(),
				summary: note.getIntro(),
				text: note.getContent(),
				keys: ''
			}),
			putreluser = Api.PutRelUser.fromObject({
				user: user.getLogin(),
				pass: user.getPassword(),
				login: user.getLogin()
			}),
			d = $q.defer();
		Api.getData(newnote, function (response) {
			if(response) {
				if(response.rez == Config.Api.validResponseValue) {
					note.setId(response.id);
					putreluser.setNid(note.getId());
					Api.getData(putreluser, function (response) {
						if (response) {
							if(response.rez == Config.Api.validResponseValue) {
								d.resolve(note);
							} else {
								d.reject(new Error.ApiError());
							}
						} else {
							d.reject(new Error.BaseError());
						}
					});
				} else {
					d.reject(new Error.ApiError());
				}
			} else {
				d.reject(new Error.BaseError());
			}
		});
		return d.promise;
	}
	return Note;
}]).
directive('noteInfo', ['Note.ConfigService', 'MainApp.ConfigService', '$rootScope', function (NoteConfig, Config, $rootScope) {
	return {
		restrict: 'E',
		templateUrl: NoteConfig.templateDir+'info'+Config.Template.directiveExt,
		replace: true,
		scope: {
			note: '=data'
		},
		controller: function ($scope) {
			$scope.setActual = function () {
				$rootScope.$broadcast('Note.setActual', $scope.note);
			}
		}
	}
}]).
directive('noteDetails', ['Note.ConfigService', 'MainApp.ConfigService', function (NoteConfig, Config) {
	return {
		restrict: 'E',
		templateUrl: NoteConfig.templateDir+'details'+Config.Template.directiveExt,
		replace: true,
		scope: {
			note: '=data'
		},
		controller: function ($scope) {
			$scope.mode = 'none';
			$scope.new = false;
			$scope.create = function () {
				$scope.$emit('Note.create', $scope.new);
				$scope.cleanNew();
				$scope.mode = 'none';
				$scope.setMode();
			}
			$scope.cleanNew = function () {
				$scope.new = {
					title: '',
					intro: '',
					content: '',
					id: false
				}	
			}
			$scope.setMode = function () {
				if($scope.note) {
					$scope.mode = 'note'
				}
			}
			$scope.save = function () {
				$scope.$emit('Note.save', $scope.note);
			}
			$scope.$on('Note.switchMode', function (event, mode) {
				$scope.mode = mode;
				console.log($scope);
			});
			// $scope.$on('Note.setActual', function (event, note) {
			// 	$scope.setMode();
			// });
			$scope.$watch('note', function () {
				$scope.setMode();
			});
			(function construct () { 
				$scope.setMode();
				$scope.cleanNew();
			})();
		}
	}
}]).
directive('noteControls', ['Note.ConfigService', 'MainApp.ConfigService', function (NoteConfig, Config) {
	return {
		restrict: 'E',
		templateUrl: NoteConfig.templateDir+'controls'+Config.Template.directiveExt,
		replace: true,
		scope: {
			note: '=data'
		},
		controller: function ($scope) {
			$scope.create = function () {
				$scope.$emit('Note.switchMode', NoteConfig.modes.create);
			}
			$scope.edit = function () {
				$scope.$emit('Note.switchMode', NoteConfig.modes.edit);
			}
			$scope.delete = function () {
				$scope.$emit('Note.delete', $scope.note);
			}
		}
	}
}])